package toolkit.tianshi.fileoperations;

import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.base.Throwables;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.Key;
import java.util.List;
import java.util.UUID;

import lombok.extern.slf4j.Slf4j;

/**
 *
 * @author zhangLin
 * @date 2016/4/18
 */
@Slf4j
public class ImageServiceImpl implements ImageServer {

    public static final char SEPARATOR = '_';
    private static int maxLimit = 2;
    private final static Splitter SPLITTER = Splitter.on(SEPARATOR).limit(maxLimit).omitEmptyStrings().trimResults();
    static Key key = new Key() {
        @Override
        public String getAlgorithm() {
            return "DSA";
        }

        @Override
        public String getFormat() {
            return null;
        }

        @Override
        public byte[] getEncoded() {
            return new byte[0];
        }
    };
    private final static HashFunction MD_5 = Hashing.hmacMd5(key);

    /**
     * 上传图片路径
     */
    @Value("#{app.imageUploadUrl}")
    private String imageUploadUrl;
    /**
     * 图片读取路径
     */
    @Value("#{app.imageBaseUrl}")
    private String imageBaseUrl;

    /**
     * @param fileName 文件名
     * @param file     文件
     * @return 文件上传后的相对路径
     */
    private String write(String fileName, MultipartFile file) throws ImageUploadException {
        InputStream is = null;
        try {
            is = file.getInputStream();
            //先判断文件是否存在
            File file1 =new File(imageUploadUrl);
            //如果文件夹不存在则创建
            if(!file1 .exists()  && !file1 .isDirectory()){
                file1 .mkdir();
            }
            File targetFile = new File(file1, fileName);
            file.transferTo(targetFile);
        } catch (java.lang.Exception e) {
            log.error("upload to nginx file server failed, exception:", e);
            throw new ImageUploadException(e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    // ignore this fxxk
                }
            }
        }
        return "/"+fileName;
    }

    /**
     * 处理原始文件名, 并返回新的文件名
     *
     * @param originalName 原始文件名
     * @param imageData    原始文件的字节数组
     * @return 新的文件名
     */
    private String handleFileName(String originalName, byte[] imageData) {
        String ext = Files.getFileExtension(originalName);
        List<String> parts = SPLITTER.splitToList(originalName);
        if (parts.size() == maxLimit) {
            String userId = parts.get(0);
            String originName = parts.get(1) + UUID.randomUUID();
            return userId + SEPARATOR + MD_5.hashString(originName, Charsets.UTF_8).toString() + "." + ext;
        } else {
            return MD_5.hashString(originalName, Charsets.UTF_8).toString() + "." + ext;
        }
    }

    @Override
    public boolean delete(String fileName) throws ImageDeleteException {
        return true;
    }

    /**
     * @param originalFilename 文件名
     * @param file             文件
     * @return 文件上传后的相对路径
     */
    @Override
    public String upload(String originalFilename, MultipartFile file) throws ImageUploadException {
        try {
            byte[] imageData = file.getBytes();
            String fileName = handleFileName(originalFilename, imageData).replaceAll("_", "");
            String filePath = write(fileName, file);
            return filePath;
        } catch (IOException e) {
            log.error("failed to upload the image,cause:{}", Throwables.getStackTraceAsString(e));
            return null;
        }
    }
}
